package com.yuyou.fn.provider.impl;

import com.google.common.collect.Collections2;
import com.yuyou.fn.api.OnlineTestService;
import com.yuyou.fn.api.dto.OnlineTestDto;
import com.yuyou.fn.api.dto.OnlineTestResultDetailDto;
import com.yuyou.fn.api.dto.OnlineTestResultDto;
import com.yuyou.fn.common.util.BeanUtils;
import com.yuyou.fn.educational.entity.Measurement;
import com.yuyou.fn.educational.entity.OnlineTest;
import com.yuyou.fn.educational.entity.OnlineTestResult;
import com.yuyou.fn.educational.entity.Student;
import com.yuyou.fn.educational.service.IMeasurementService;
import com.yuyou.fn.educational.service.IOnlineTestResultService;
import com.yuyou.fn.educational.service.IOnlineTestService;
import com.yuyou.fn.educational.service.IStudentService;

import javax.annotation.Resource;
import java.util.*;

public class ExposeOnlineTestServiceImpl implements OnlineTestService {

    @Resource
    private IOnlineTestService onlineTestService ;

    @Resource
    private IOnlineTestResultService onlineTestResultService;

    @Resource
    private IMeasurementService measurementService;

    @Resource
    private IStudentService studentService ;

    @Override
    public Collection<OnlineTestDto> findOnlineTestOfStudent(Long studentId) {
        List<OnlineTest> onlineTests = onlineTestService.findOnlineTestForTests(studentId);
        List<Long> onlineTestIds  = BeanUtils.toList(onlineTests,"onlineTestId");
        List<OnlineTestResult> results = onlineTestService.findOnlineTestResults(onlineTestIds);
        Map<Long,List<OnlineTestResult>> onlineTestId2OnlineTestResult =  BeanUtils.toGroup(results,"onlineTestId");
        List<OnlineTestDto> dtos = new ArrayList<>(onlineTests.size());
        for(OnlineTest onlineTest : onlineTests ){
            OnlineTestDto onlineTestDto = new OnlineTestDto();
            BeanUtils.copyProperties(onlineTestDto,onlineTest);
            List<OnlineTestResult> onlineTestResults = onlineTestId2OnlineTestResult.get(onlineTest.getOnlineTestId());
            if(onlineTestResults == null ){
                onlineTestResults= Collections.EMPTY_LIST ;
            }
            onlineTestDto.setResults(Collections2.transform(onlineTestResults ,this::toOnlineTestResultDto));
            dtos.add( onlineTestDto );
        }

        return dtos;
    }



    @Override
    public OnlineTestResultDto beginTesting(Long onlineTestId) {
        OnlineTestResult onlineTestResult = onlineTestService.beginTesting(onlineTestId);
        return toOnlineTestResultDto(onlineTestResult);
    }

    @Override
    public void saveTestResult(Long onlineTestResultId, Integer testDuration, String answerDetail, Boolean isComplete) {
        onlineTestService.saveTestResult(onlineTestResultId , testDuration , answerDetail ,isComplete ) ;
    }

    @Override
    public OnlineTestResultDetailDto findOnlineTestResultDetail(Long onlineTestResultId) {
        OnlineTestResult onlineTestResult = onlineTestResultService.findById(onlineTestResultId );
        OnlineTest onlineTest = onlineTestService.findById(onlineTestResult.getOnlineTestId());
        List<Measurement> measurements = measurementService.findReachMeasurementForScore(onlineTest.getCampusId(), onlineTest.getGradeId(), onlineTest.getSubjectId(), onlineTestResult.getScore());
        Student student = studentService.findById(onlineTest.getStudentId());
        List<Integer> levels = new ArrayList<>(measurements.size());
        for(Measurement measurement : measurements ){
            levels.add(measurement.getLevel());
        }
        OnlineTestResultDetailDto onlineTestResultDetailDto = new OnlineTestResultDetailDto();
        BeanUtils.copyProperties(onlineTestResultDetailDto,onlineTestResult);
        onlineTestResultDetailDto.setGradeId(onlineTest.getGradeId());
        onlineTestResultDetailDto.setGradeName(onlineTest.getGradeName());
        onlineTestResultDetailDto.setSubjectId(onlineTest.getSubjectId());
        onlineTestResultDetailDto.setSubjectName(onlineTest.getSubjectName());
        onlineTestResultDetailDto.setScore(onlineTestResult.getScore());
        onlineTestResultDetailDto.setStudentId(student.getStudentId());
        onlineTestResultDetailDto.setStudentName(student.getName());
        onlineTestResultDetailDto.setLevels(levels);
        return onlineTestResultDetailDto;
    }

    private OnlineTestResultDto toOnlineTestResultDto(OnlineTestResult olr) {
        OnlineTestResultDto onlineTestResultDto = new OnlineTestResultDto();
        BeanUtils.copyProperties(onlineTestResultDto,olr);
        return onlineTestResultDto ;
    }
}
